﻿/*************************************************
  * 描述：生成码图像的私有类
  *
  * File：codeimagegenerator_p.h
  * Author：gaomaolong@mozihealthcare.cn
  * Date：2025-09-22
  * Update：
  * ************************************************/

#ifndef CODEIMAGEGENERATORPRIVATE_H
#define CODEIMAGEGENERATORPRIVATE_H

#include <common/codeimagegenerate/codeimageconfig.h>
#include <common/codeimagegenerate/codeimagegenerator.h>
#include <zint.h>

class CodeImageGeneratorPrivate
{

	Q_DECLARE_PUBLIC(CodeImageGenerator)

public:
	/**
	 * 构造函数
	 * @param q 公有类指针
	 */
	explicit CodeImageGeneratorPrivate(CodeImageGenerator* q);

	/**
	 * 重载构造函数
	 * @param q 公有类指针
	 * @param config 生成码的配置
	 */
	explicit CodeImageGeneratorPrivate(CodeImageGenerator* q, const CodeImageConfig& config);

	/**
	 * 析构函数
	 */
	~CodeImageGeneratorPrivate();

	/**
	 * 首先会判断对象是否已经设置了config，如果没有则使用默认的config，并根据数据长度自动选择生成码的类型
	 * 如果之前已经设置过config，那么复用已存在的config
	 * @param data 生成码的数据
	 * @return QImage 生成的码图像
	 */
	QImage generate(const QString& data);

	/**
	 * 使用于创建对象调用，生成码
	 * @param data 要生成码的数据
	 * @param config 要生成码的配置
	 * @return QImage 生成的码图像
	 */
	QImage generate(const QString& data, const CodeImageConfig& config);

	/**
	 * 获取支持的码格式列表
	 * @return
	 */
	static QList<BarcodeType> getSupportedFormats();

	/**
	 * 设置生成码的config
	 * @param config 配置
	 */
	void setCodeImageConfig(const CodeImageConfig& config);


private:
	/**
	 * 检查传入数据是否符合CODE_128的要求
	 * @param data 检验数据
	 * @return 错误日志，如果数据合法，返回空字符串
	 * */
	QString checkCode128(const QString& data) const;

	/**
	 * 检查传入数据是否符合EAN_13的要求
	 * @param data 要检验的数据
	 * @return 错误日志，如果数据合法，返回空字符串
	 */
	QString checkEAN_13(const QString& data) const;

	/**
	 * 检验传入数据是否合法,主要是检验数据长度
	 * @param data 传入数据
	 * @param type 码类型
	 * @return true 合法 false 不合法
	 */
	QString isValidData(const QString& data, BarcodeType type) const;

	/**
	 * 根据配置设置Zint符号参数（核心方法)
	 * @param config 自定义结构体，里面配置了生成码的各种参数
	 */
	void setupSymbol(const CodeImageConfig& config);

	/**
	 * 将Zint的bitmap缓冲区转换为QImage
	 * @param symbol Zint符号实例
	 * @return QImage 转换后的图像
	 */
	QImage zintBufferToQImage(zint_symbol* symbol) const;

	/**
	* 添加图标到二维码中间
	* @param barcode 二维码图像
	* @param iconConfig 图标配置
	* @return 带有图标的二维码图像
	*/
	QImage addCenterIcon(const QImage& barcode, const IconConfig& iconConfig);

	/**
	 * 主要用来将枚举转化为string，打印日志使用
	 * @param type 枚举值
	 * @return 枚举的字符串
	 */
	QString barcodeTypeToString(BarcodeType type);


	/**
	 *二维码缩放逻辑
	*/
	QImage scaleQRImage() const;

	/**
	* 条形码缩放逻辑
	 * @return
	*/
	QImage scaleBarcodeImage() const;

	/**
	 * 将原始码图像缩放到指定大小
	 * @param width 宽度
	 * @param pixels 原像素数组
	 * @param scaleFactor 缩放因子
	 * @param scaledWidth 缩放后的宽度
	 * @param scaledHeight 缩放后的高度
	 * @param scaledPixels 缩放后的像素数组
	 */
	void orignal2ScaledBitmap(int width, unsigned char* pixels, int scaleFactor,
							  int scaledWidth, int scaledHeight, unsigned char* scaledPixels) const;

	/**
	 * 将缩放后的码图像填充白边到指定大小
	 * @param m_width 最终宽度
	 * @param m_height 最终高度
	 * @param scaledWidth 缩放后的宽度
	 * @param scaledHeight 缩放后的高度
	 * @param scaledPixels 缩放后的像素数组
	 * @param finalPixels 最终的像素数组
	 * @param harfMarginX 距离中心点的横向偏移
	 * @param modedMarginX 距离中心点的横向偏移+1
	 * @param harfMarginY 距离中心点的纵向偏移
	 * @param modedMarginY 距离中心点的纵向偏移+1
	 */
	void scaled2FilledWrite(int m_width, int m_height, int scaledWidth, int scaledHeight, unsigned char* scaledPixels,
							unsigned char* finalPixels, int harfMarginX, int modedMarginX, int harfMarginY, int modedMarginY) const;


private:
	CodeImageGenerator* q_ptr;// 指向公共类的指针
	zint_symbol* m_symbol;    // Zint 符号实例，用于生成码的核心结构体，在zint库中定义
	CodeImageConfig m_config; // 当前配置（根据config构建symbol）
	bool isConfigured;        // 是否已经配置过symbol
};


#endif//CODEIMAGEGENERATORPRIVATE_H
